#include "Z_Buffer.h"
#include "Drawer.h"
#include <algorithm>

namespace HW2
{

	void Z_Buffer::set(Coordinates p, Color c)
	{
		Point2D p2= p.toPoint2D();
		if(data.empty() || data[0].empty() || p2.x >= data.size() || p2.y >= data[0].size() ||p2.x <0 ||p2.y < 0)
			return;
	
		PixelInfo &info = data[p2.x][p2.y];
		if(!info.valid || info.depth > p.Z())
		{
			info = PixelInfo(p.Z(), c);
		}

		transparencyData[p2.x][p2.y].push_back(PixelInfo(p.Z(), c));

	}

	void Z_Buffer::clear()
	{
		data.clear();
		transparencyData.clear();
	}

	Color getTransparentColor(std::vector<PixelInfo> &infos)
	{
		if(infos.empty())
			return Color();
		std::sort(infos.rbegin(), infos.rend());
		Color c = infos[0].color;
		//*
		for(unsigned int i = 1; i < infos.size(); ++i)
		{
			//if(abs(infos[i].depth - infos[i-1].depth)> 1e-4 )
			c.interpolate(infos[i].color);
		}
		//*/
		return c;
	}
	

	void Z_Buffer::draw(Plotter &p)
	{ 
		for(unsigned int x = 0; x < data.size(); ++x)
		{
			for(unsigned int y = 0; y < data[0].size(); ++y)
			{
				if(data[x][y].valid)
				{
					double z = data[x][y].depth;	
					p.plot(x,y,z, data[x][y].color);
				}
			}
		}
	}
	void Z_Buffer::drawTransparency(Plotter &p)
	{ 
		for(unsigned int x = 0; x < transparencyData.size(); ++x)
		{
			for(unsigned int y = 0; y < transparencyData[0].size(); ++y)
			{
				p.plot(x,y,0,getTransparentColor(transparencyData[x][y]));
			}
		}
	}


	void Z_Buffer::plot(int x, int y, double z, Color c, Coordinates orig)
	{
		set(Coordinates(x,y,z),c);
	}

	void Z_Buffer::fillBackground(Color c)
	{
		for(unsigned int i = 0; i < data.size(); ++i)
		{
			for(unsigned int j = 0; j < data[0].size(); ++j)
			{
				set(Coordinates(i,j,DBL_MAX), c);
			}
		}
	}
}